package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.AipFaceTemplate;
import com.itheima.autoconfig.HuanXinTemplate;
import com.itheima.autoconfig.OssTemplate;
import com.itheima.autoconfig.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.UserInfoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class UserManager {

    @DubboReference
    private UserService userService;

    // 保存用户
    public ResponseEntity save(User user) {
        Long userId = userService.save(user);
        return ResponseEntity.ok(userId); // 状态码200，响应体数据 101 用户id
    }

    // 查询用户
    public ResponseEntity findByPhone(String phone) {
        User user = userService.findByPhone(phone);
        return ResponseEntity.ok(user);// 状态码200，响应体数据 {xxx:xxx} 用户对象
    }

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 发送验证码
    public void sendSms(String phone) {
        // 1.生成验证码
        String smsCode = RandomUtil.randomNumbers(6);
        smsCode = "123456";
        // 2.阿里云发短信
        //  smsTemplate.sendSms(phone, smsCode); // TODO 产品上线后再发送
        // 3.redis存验证码  5分钟 Minutes
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, smsCode, Duration.ofMinutes(5));
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 注册、登录
    public ResponseEntity loginVerification(String phone, String verificationCode) {
        // 1.取出redis验证码
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        // 2.比对验证码
        if (!StrUtil.equals(verificationCode, redisCode)) {
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        // 3.根据手机号查询用户
        User user = userService.findByPhone(phone);
        // 判断
        Boolean isNew;
        String type = null;
        if (user != null) { // 老用户
            isNew = false;
            type = "0101";
        } else { // 新用户
            isNew = true;
            // 封装user实体
            user = new User();
            user.setMobile(phone);
            user.setPassword(ConstantUtil.INIT_PASSWORD);
            // 调用rpc保存
            Long userId = userService.save(user);
            // 设置新用户的userId
            user.setId(userId);

            // 注册环信
            huanXinTemplate.register("HX" + userId);

            type = "0102";
        }
        // 4.制作令牌
        user.setPassword(null);
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        String token = JwtUtil.createToken(claims);
        // 5.redis存储 有效期7天
        String json = JSON.toJSONString(user);
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));

        // redis中验证码作废
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);

        //------------------
        // 封装log对象
        Log log = new Log();
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.formatDate(new Date())); // formatDate()格式：2022-03-26
        log.setPlace("北京顺义黑马程序员");
        log.setEquipment("华为Mate40");
        log.setType(type); // 登录 or 注册
        // 发送mq日志消息
        rabbitTemplate.convertAndSend("tanhua.log", log);
        //------------------

        // 6.返回结果
        Map resultMap = new HashMap();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);
        return ResponseEntity.ok(resultMap);
    }

    @DubboReference
    private UserInfoService userInfoService;

    // 完善用户信息
    public void loginReginfo(UserInfo userInfo, String token) {
        // 1.解析token获取user
        User user = findUserByToken(token);
        // 2.将userId设置到userInfo
        userInfo.setId(user.getId());
        // 3.调用rpc保存
        userInfoService.save(userInfo);
    }

    // 解析token获取user
    public User findUserByToken(String token) {
        // 检测redis中是否有token
        Boolean isCheck = stringRedisTemplate.hasKey(ConstantUtil.USER_TOKEN + token);
        if (isCheck == true) { // 登录
            // 获取用户信息
            String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
            User user = JSON.parseObject(json, User.class);
            // 续期7天
            stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, json, Duration.ofDays(7));
            // 返回user对象
            return user;
        }
        return null;// 未登录
    }

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    // 完善头像信息
    public ResponseEntity loginReginfoHead(MultipartFile headPhoto) throws Exception {
        // 1.人脸检测
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (detect == false) { // 非人像
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }
        // 2.oss人像上传
        String picUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        // 3.获取线程内user对象
        User user = UserHolder.get();
        //  4.封装userInfo
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId()); // 用户id
        userInfo.setAvatar(picUrl); // 用户头像
        userInfo.setCoverPic(picUrl); // 用户封面
        // 5.调用rpc更新
        userInfoService.update(userInfo);
        return ResponseEntity.ok(null);
    }

    // 查询用户基本信息
    public ResponseEntity findUserInfoVo(Long userID) {
        // 1.查询userInfo
        UserInfo userInfo = userInfoService.findById(userID);
        //2.封装vo
        UserInfoVo vo = new UserInfoVo();
        BeanUtil.copyProperties(userInfo, vo);
        // 3.返回vo
        return ResponseEntity.ok(vo);
    }

    // 更新用户基本信息
    public void putUserInfo(UserInfo userInfo) {
        // 调用rpc更新
        userInfoService.update(userInfo);
    }
}
